<?php
declare(strict_types=1);

namespace App\Logic\Exam;

use App\Library\SnowFlakeId;
use App\Logic\BaseUserService;
use App\Model\User\Exam\UserCollection;
use App\Model\User\Exam\UserCollectionSubmitUserHistory;
use App\Model\User\Exam\UserJude;
use App\Model\User\Exam\UserOption;
use App\Model\User\Exam\UserSubmit;
use Illuminate\Support\Facades\DB;

/**
 * 考试答题记录
 * @project: 兔兔考试系统
 * @author: Mandy
 * @date: 2023/08/04
 * @link: https://www.tutudati.com/
 * @site: 微信搜索-兔兔考试系统
 */
class SubmitService extends BaseUserService
{
    // 记录答题记录
    public function submitService(): array
    {
        // 提取提交试题中的uid，根据uid查询到对应的积分和答案
        $requestParams = request()->all();
        $optionUidArray = $judeUidArray = $judeAnswerArray = $optionAnswerArray = [];
        $record = json_decode($requestParams["record"], true);
        foreach ($record as $value) {
            if ($value["originType"] == "option") {
                $optionUidArray[] = $value["uid"];
                $answerArray = [];
                foreach ($value["answer"] as $v) {
                    $answerArray[] = $v["answer"];
                }
                sort($answerArray);
                $optionAnswerArray[$value["uid"]] = $answerArray;
            } elseif ($value["originType"] == "jude") {
                $judeUidArray[] = $value["uid"];
                $judeAnswerArray[$value["uid"]] = ($value["answer"][0]["answer"] == "A" ? 0 : 1);
            }
        }
        $optionItemList = UserOption::query()
            ->whereIn("uid", $optionUidArray)
            ->get(["uid", "answer", "score"])
            ->toArray();
        $jueItemList = UserJude::query()
            ->whereIn("uid", $judeUidArray)
            ->get(["uid", "is_correct", "score"])
            ->toArray();
        $submitScore = 0;
        $submitHistory = [];
        $collectionUid = $requestParams["collection_uid"];
        $examSubmitUid = SnowFlakeId::getId();
        $correctCount = 0;
        foreach ($optionItemList as $value) {// 处理选择题
            $history = [
                "uid" => SnowFlakeId::getId(),
                "ex_exam_submit" => $examSubmitUid,
                "user_uid" => $this->getUserUid(),
                "collection_uid" => $collectionUid,
                "exam_uid" => $value["uid"],
                "type" => "option",
                "answer" => json_encode($optionAnswerArray[$value["uid"]]),
                "origin_answer" => json_encode($value["answer"]),
                "score" => 0.00,
                "origin_score" => $value["score"],
                "created_at" => date("Y-m-d H:i:s"),
                "updated_at" => date("Y-m-d H:i:s"),
            ];
            if (empty(array_diff($value["answer"], $optionAnswerArray[$value["uid"]]))) {
                $submitScore += $value["score"];
                $history["score"] = $value["score"];
                ++$correctCount;
            }
            $submitHistory[] = $history;
        }
        foreach ($jueItemList as $value) {// 处理问答题
            $history = [
                "uid" => SnowFlakeId::getId(),
                "ex_exam_submit" => $examSubmitUid,
                "user_uid" => $this->getUserUid(),
                "collection_uid" => $collectionUid,
                "exam_uid" => $value["uid"],
                "type" => "jude",
                "answer" => $judeAnswerArray[$value['uid']],
                "origin_answer" => $value["is_correct"],
                "score" => 0.00,
                "origin_score" => $value["score"],
                "created_at" => date("Y-m-d H:i:s"),
                "updated_at" => date("Y-m-d H:i:s"),
            ];
            if ($value["is_correct"] == $judeAnswerArray[$value["uid"]]) {
                $submitScore += $value["score"];
                $history["score"] = $value["score"];
                ++$correctCount;
            }
            $submitHistory[] = $history;
        }
        $collectionInfo = UserCollection::query()->where([
            ["uid", "=", $collectionUid]
        ])->first(["time"]);
        $examSubmit = [
            "uid" => $examSubmitUid,
            "user_uid" => $this->getUserUid(),
            "collection_uid" => $collectionUid,
            "score" => $submitScore,
            "exam_count" => count($jueItemList) + count($optionItemList),
            "correct_count" => $correctCount,
            "error_count" => count($jueItemList) + count($optionItemList) - $correctCount,
            "submit_time" => $collectionInfo->time,
        ];
        // 创建记录
        DB::beginTransaction();
        try {
            $examSubmitModel = UserSubmit::query()->create($examSubmit);
            $examHistory = DB::table("ex_exam_submit_history")->insert($submitHistory);
            UserCollection::query()->where("uid", "=", $collectionUid)->increment("submit");
            UserCollectionSubmitUserHistory::query()->create([
                "collection_uid" => $collectionUid,
                "user_uid" => $this->getUserUid(),
                "uid" => SnowFlakeId::getId()
            ]);
            if ($examHistory && !empty($examSubmitModel->getKey())) {
                DB::commit();
                return [
                    "errcode" => 0,
                    "errmsg" => "提交成功",
                    "submit_uid" => $examSubmitUid,
                ];
            }
            DB::rollBack();
            return ["errcode" => 1, "errmsg" => "提交失败",];
        } catch (\Exception $exception) {
            DB::rollBack();
            return ["errcode" => 1, "errmsg" => env("APP_DEBUG") ? $exception->getMessage() : "系统异常"];
        }
    }

    // 获取答题结果详情
    public function getSubmitDetailService(): array
    {
        $requestParams = request()->all();
        if (!empty($requestParams["submit_uid"])) {
            $bean = UserSubmit::query()
                ->where([
                    ["uid", "=", $requestParams["submit_uid"]],
                    ["user_uid", "=", $this->getUserUid()]
                ])->first(["score", "exam_count", "correct_count", "error_count", "collection_uid", "submit_time"]);
            $collection = UserCollection::query()
                ->where("uid", "=", $bean->collection_uid)
                ->first(["uid", "title"]);
            return [
                "collection" => $collection->toArray(),
                "submit" => $bean->toArray(),
            ];
        }
        return [];
    }

    // 获取答题历史记录
    public function getHistoryList(): array
    {
        $requestParams = request()->all();
        $items = UserSubmit::query()
            ->with(["collection:uid,title,url,path"])
            ->where([
                ["user_uid", "=", $this->getUserUid()]
            ])
            ->orderByDesc("id")
            ->paginate(
                (int)($requestParams["size"] ?? 20),
                ["score", "uid", DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d') as submit_date"), "correct_count", "error_count", "collection_uid"]
            );

        return [
            "items" => $items->items(),
            "page" => $items->currentPage(),
            "total" => $items->total(),
            "size" => (int)($requestParams["size"] ?? 20),
        ];
    }

    // 获取答题排名前10
    public function getSubmitRankList(): array
    {
        $requestParams = request()->all();
        if (!empty($requestParams["collection_uid"])) {
            return UserSubmit::query()
                ->with(["user:uid,nickname,avatar_url"])
                ->where([
                    ["collection_uid", "=", $requestParams["collection_uid"]]
                ])
                ->groupBy("user_uid")
                ->orderByDesc("score")
                ->limit(10)
                ->get(["user_uid", DB::raw("sum(score) as score")])
                ->toArray();
        }
        return [];
    }
}
